//
// Created on 2022/12/12.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#ifndef ijkplayer_mediacodec_videodec_H
#define ijkplayer_mediacodec_videodec_H
#include <atomic>
#include <fstream>
#include <thread>
#include <string>
#include "napi/native_api.h"
#include "native_common.h"
#include <ace/xcomponent/native_interface_xcomponent.h>
#include "log/ohos_log.h"
#include "multimedia/player_framework/native_averrors.h"
#include "multimedia/player_framework/native_avformat.h"
#include "multimedia/player_framework/native_avmemory.h"
#include "multimedia/player_framework/native_avcodec_videodecorder.h"

class VDecSignal{
    public:
      std::queue<uint32_t> inQueue_;
      std::queue<uint32_t> outQueue_;
      std::mutex vdecInpMutex_;
      std::mutex vdecOutMutex_;
      std::condition_variable vdecInCond_;
      std::condition_variable vdecOutCond_;
      std::atomic<bool> isVdecFlushing_;
      std::queue<OH_AVMemory *> vdecInpBufferQueue_;
      std::queue<uint32_t> vdecOutFlagQueue_; 
      int32_t errorNum_=0;
};

class VCodecNdkSample {
    public:
    VCodecNdkSample() = default;
    virtual ~VCodecNdkSample() = default;
    static napi_value videoDec(napi_env env,napi_callback_info info);
    void VDecInpLoopFunc();
    void VDecOutLoopFunc();
    VCodecNdkSample(std::string &id);
    static VCodecNdkSample *GetInstance(){
        return &VCodecNdkSample::mCodecNdkSample;
    }
    static OH_NativeXComponent_Callback *GetNXComponentCallback();
    void SetNativeXComponent(OH_NativeXComponent *component);
    void OnSurfaceCreated(OH_NativeXComponent *component,void *window);
    void OnSurfaceChanged(OH_NativeXComponent *component,void *window);
    void OnSurfaceDestroyed(OH_NativeXComponent *component,void *window);
    void DispatchTouchEvent(OH_NativeXComponent *component,void *window);
    static OH_NativeXComponent_Callback callback_;
    OH_NativeXComponent *component_;
    std::string id_;
    uint64_t width_;
    uint64_t height_;
    double x_;
    double y_;
    OH_NativeXComponent_TouchEvent touchEvent_;
    bool Export(napi_env env,napi_callback_info exports);
    struct OH_AVCodec *CreateVideoDecoder(void);
    void PopInqueueDec();
    void PopOutqueueDec();
    int32_t PushInbufferDec(uint32_t index,uint32_t bufferSize);
    int32_t FlushDec();
    void clearIntqueue(std::queue<uint32_t> &q);
    
    public:
    static VCodecNdkSample mCodecNdkSample;
    std::atomic<bool> isRunning_;
    static std::unique_ptr<std::ifstream> testFile_;
    static std::unique_ptr<std::thread> readLoop_;
    static std::unique_ptr<std::thread> vdecOutLoop_;
    static std::unique_ptr<std::thread> inputLoop_;
    static std::unique_ptr<std::thread> outputLoop_;
    static VDecSignal *signal_;
    bool isFirstFrame_ = true;
    int64_t timeStampDec_ = 0;
    int32_t frameCount_ = 0;
    int32_t vdecFrameCount_ = 0;
    bool isFirstDecFrame_ = true;
    int32_t desInCnt_ = 0;
    bool isDecInputEOS=false;
};




#endif //ijkplayer_mediacodec_videodec_H
